﻿/*
 * ©2009-2010 XELF
 * http://xelf.info
 */

#if XNA || WINDOWS_PHONE
using Microsoft.Xna.Framework;
#endif

namespace XELF.Framework {
	/// <summary>
	/// 4行4列の行列
	/// </summary>
#if XNA || WINDOWS_PHONE
#else
	public partial struct Matrix {
		/// <summary>M11</summary>
		public float M11;
		/// <summary>M12</summary>
		public float M12;
		/// <summary>M13</summary>
		public float M13;
		/// <summary>M14</summary>
		public float M14;
		/// <summary>M21</summary>
		public float M21;
		/// <summary>M22</summary>
		public float M22;
		/// <summary>M23</summary>
		public float M23;
		/// <summary>M24</summary>
		public float M24;
		/// <summary>M31</summary>
		public float M31;
		/// <summary>M32</summary>
		public float M32;
		/// <summary>M33</summary>
		public float M33;
		/// <summary>M34</summary>
		public float M34;
		/// <summary>M41</summary>
		public float M41;
		/// <summary>M42</summary>
		public float M42;
		/// <summary>M43</summary>
		public float M43;
		/// <summary>M44</summary>
		public float M44;
	}
#endif
}

namespace XELF.Framework {
#if XNA || WINDOWS_PHONE
#else
	public partial struct Matrix {
		/// <summary>
		/// コンストラクタ
		/// </summary>
		/// <param name="m11"></param>
		/// <param name="m12"></param>
		/// <param name="m13"></param>
		/// <param name="m14"></param>
		/// <param name="m21"></param>
		/// <param name="m22"></param>
		/// <param name="m23"></param>
		/// <param name="m24"></param>
		/// <param name="m31"></param>
		/// <param name="m32"></param>
		/// <param name="m33"></param>
		/// <param name="m34"></param>
		/// <param name="m41"></param>
		/// <param name="m42"></param>
		/// <param name="m43"></param>
		/// <param name="m44"></param>
		public Matrix(float m11, float m12, float m13, float m14,
			float m21, float m22, float m23, float m24,
			float m31, float m32, float m33, float m34,
			float m41, float m42, float m43, float m44) {
			M11 = m11; M12 = m12; M13 = m13; M14 = m14;
			M21 = m21; M22 = m22; M23 = m23; M24 = m24;
			M31 = m31; M32 = m32; M33 = m33; M34 = m34;
			M41 = m41; M42 = m42; M43 = m43; M44 = m44;
		}
	}

	public partial struct Matrix {
		/// <summary>
		/// 並行移動成分
		/// </summary>
		public Vector3 Translation {
			get { return new Vector3(M41, M42, M43); }
			set { M41 = value.X; M42 = value.Y; M43 = value.Z; }
		}
		/// <summary>
		/// 
		/// </summary>
		/// <returns></returns>
		public override string ToString() {
			return string.Format(
				"{{{0},{1},{2},{3}}}, {{{4},{5},{6},{7}}}, {{{8},{9},{10},{11}}}, {{{12},{13},{14},{15}}}",
				M11, M12, M13, M14,
				M21, M22, M23, M24,
				M31, M32, M33, M34,
				M41, M42, M43, M44);
		}
	}
#endif
}

namespace XELF.Framework {
#if XNA || WINDOWS_PHONE
	public static partial class MatrixHelper {
#else
	public partial struct Matrix {
#endif
		static readonly Matrix identity = new Matrix(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);

		/// <summary>
		///	単位行列（乗法の単位元）
		/// </summary>
		public static Matrix Identity { get { return identity; } }
	}
}

namespace XELF.Framework {
#if XNA || WINDOWS_PHONE
	public static partial class MatrixHelper {
#else
	public partial struct Matrix {
#endif
		public static bool AreEqual(ref Matrix a, ref Matrix b, float delta) {
			return
				MathHelper.AreEqual(a.M11, b.M11, delta) &&
				MathHelper.AreEqual(a.M12, b.M12, delta) &&
				MathHelper.AreEqual(a.M13, b.M13, delta) &&
				MathHelper.AreEqual(a.M14, b.M14, delta) &&
				MathHelper.AreEqual(a.M21, b.M21, delta) &&
				MathHelper.AreEqual(a.M22, b.M22, delta) &&
				MathHelper.AreEqual(a.M23, b.M23, delta) &&
				MathHelper.AreEqual(a.M24, b.M24, delta) &&
				MathHelper.AreEqual(a.M31, b.M31, delta) &&
				MathHelper.AreEqual(a.M32, b.M32, delta) &&
				MathHelper.AreEqual(a.M33, b.M33, delta) &&
				MathHelper.AreEqual(a.M34, b.M34, delta) &&
				MathHelper.AreEqual(a.M41, b.M41, delta) &&
				MathHelper.AreEqual(a.M42, b.M42, delta) &&
				MathHelper.AreEqual(a.M43, b.M43, delta) &&
				MathHelper.AreEqual(a.M44, b.M44, delta);
		}
	}

}
